from robot.api import logger

from ...common.element_function import ElementFunction
from ...exception.TestException import TestException
from ...exception.errorcode import ErrorCode


class Menu(object):
    """菜单不做为PageElement元素，所以不继承PageElement
    """
    def __init__(self, driver):
        self._driver = driver

    def open_menu(self, *menus):
        pre_element = None
        for menu in menus:
            logger.debug('try to open menu: {0}'.format(menu))
            menu_element = self._find_menu_element(menu)
            if menu_element is None:
                raise TestException.by_error_code(ErrorCode.NOT_LOCATE_ELEMENT, selector_type='XPATH-menu',
                                                  selector=menu)
            # 如果当前菜单没显示出来，需要尝试再点击上一级菜单
            if pre_element and not ElementFunction.wait_element_displayed(menu_element):
                logger.debug('try to click parent menu item to open child menu item')
                ElementFunction(self._driver).click(pre_element)

            # 如果上一级菜单刚刚点击过了，需要再等待当前菜单显示
            if ElementFunction.wait_element_displayed(menu_element):
                ElementFunction(self._driver).click(menu_element)
            else:
                raise TestException.by_error_code(ErrorCode.ELEMENT_CLICK_INTERCEPTED)

            pre_element = menu_element

    def _find_menu_element(self, menu_name: str, timeout: int = 2):
        selectors_template = [
            '//li[contains(@class,"ant-menu-submenu")]//span[text()="{0}"]',
            '//li[contains(@class,"ant-menu-item") and text()="{0}"]',
            '//li[contains(@class,"ant-menu-submenu")]//div[text()="{0}"]',
            '//li[contains(@class,"ant-menu-item")]//span[text()="{0}"]',
        ]
        menu_element = None
        for selector_template in selectors_template:
            selector = selector_template.format(menu_name)
            menu_element = ElementFunction(self._driver).try_find_element_in_page(selector)
            if menu_element:
                logger.debug("Get menu item: {0}".format(selector))
                break
        return menu_element
